<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>files-preview</title>
  <meta name="referrer" content="never">
  <style src="./index.css"></style>
  <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>

<body>
  <div id="app">
    <div class="fp-doc">
      <header class="fp-doc-navbar">
        <div class="fp-doc-logo">
          <div class="fp-menu-icon-wrap">
            <div :class="['fp-menu-icon',{close:!hideTree}]" @click="hideTree = !hideTree">
              <span class="fp-menu-line"></span>
              <span class="fp-menu-line"></span>
              <span class="fp-menu-line"></span>
            </div>
          </div>
          <a href="/" class="logo">
            <svg width="95" height="26" viewBox="0 0 95 26" fill="none" xmlns="http://www.w3.org/2000/svg">
              <path d="M0 24V2.70001H14.61V7.80001H5.85V11.34H12.99V16.08H5.85V24H0Z" fill="#2D3748" />
              <path
                d="M17.0543 24V2.70001H26.2343C27.2743 2.70001 28.2343 2.91001 29.1143 3.33001C29.9943 3.75001 30.7543 4.32001 31.3943 5.04001C32.0343 5.74001 32.5243 6.53001 32.8643 7.41001C33.2243 8.29001 33.4043 9.18001 33.4043 10.08C33.4043 11.34 33.1043 12.53 32.5043 13.65C31.9243 14.77 31.1043 15.69 30.0443 16.41C29.0043 17.11 27.7843 17.46 26.3843 17.46H22.9043V24H17.0543ZM22.9043 12.36H25.9943C26.3543 12.36 26.6843 12.2 26.9843 11.88C27.3043 11.54 27.4643 10.94 27.4643 10.08C27.4643 9.20001 27.2843 8.60001 26.9243 8.28001C26.5643 7.96001 26.2043 7.80001 25.8443 7.80001H22.9043V12.36Z"
                fill="#2D3748" />
              <rect x="39" width="56" height="26" rx="4" fill="#2D3748" />
              <path
                d="M46.0879 19V7.64001H50.3279C51.5759 7.64001 52.6159 7.89601 53.4479 8.40801C54.2906 8.90934 54.9252 9.59201 55.3519 10.456C55.7786 11.3093 55.9919 12.2587 55.9919 13.304C55.9919 14.456 55.7572 15.4587 55.2879 16.312C54.8186 17.1653 54.1572 17.8267 53.3039 18.296C52.4612 18.7653 51.4692 19 50.3279 19H46.0879ZM53.3199 13.304C53.3199 12.3013 53.0586 11.4907 52.5359 10.872C52.0132 10.2533 51.2772 9.94401 50.3279 9.94401H48.7119V16.696H50.3279C50.9679 16.696 51.5119 16.552 51.9599 16.264C52.4079 15.9653 52.7439 15.56 52.9679 15.048C53.2026 14.536 53.3199 13.9547 53.3199 13.304Z"
                fill="white" />
              <path
                d="M62.597 19.096C61.7543 19.096 60.9863 18.936 60.293 18.616C59.6103 18.2853 59.0183 17.848 58.517 17.304C58.0157 16.7493 57.6317 16.1307 57.365 15.448C57.0983 14.7547 56.965 14.04 56.965 13.304C56.965 12.5573 57.1037 11.8427 57.381 11.16C57.669 10.4667 58.0637 9.85334 58.565 9.32001C59.077 8.77601 59.6797 8.34934 60.373 8.04001C61.0663 7.73067 61.8237 7.57601 62.645 7.57601C63.4877 7.57601 64.2503 7.74134 64.933 8.07201C65.6263 8.39201 66.2184 8.82934 66.709 9.38401C67.2104 9.93867 67.5943 10.5627 67.861 11.256C68.1277 11.9387 68.261 12.6373 68.261 13.352C68.261 14.0987 68.117 14.8187 67.829 15.512C67.5517 16.1947 67.157 16.808 66.645 17.352C66.1437 17.8853 65.5463 18.312 64.853 18.632C64.1703 18.9413 63.4183 19.096 62.597 19.096ZM59.637 13.336C59.637 13.9227 59.749 14.4773 59.973 15C60.197 15.512 60.533 15.9333 60.981 16.264C61.429 16.5947 61.973 16.76 62.613 16.76C63.2743 16.76 63.8237 16.5893 64.261 16.248C64.709 15.9067 65.0397 15.4747 65.253 14.952C65.477 14.4187 65.589 13.8693 65.589 13.304C65.589 12.7173 65.4717 12.168 65.237 11.656C65.013 11.1333 64.677 10.712 64.229 10.392C63.7917 10.072 63.253 9.91201 62.613 9.91201C61.9517 9.91201 61.397 10.0827 60.949 10.424C60.5117 10.7547 60.181 11.1813 59.957 11.704C59.7437 12.2267 59.637 12.7707 59.637 13.336Z"
                fill="white" />
              <path
                d="M69.2013 13.224C69.2013 12.5413 69.3293 11.864 69.5853 11.192C69.8413 10.52 70.2146 9.91201 70.7053 9.36801C71.1959 8.82401 71.7933 8.39201 72.4973 8.07201C73.2013 7.74134 74.0013 7.57601 74.8973 7.57601C75.9533 7.57601 76.8759 7.80534 77.6653 8.26401C78.4546 8.72267 79.0413 9.32001 79.4253 10.056L77.4093 11.464C77.2386 11.0693 77.0093 10.76 76.7213 10.536C76.4333 10.3013 76.1239 10.1413 75.7933 10.056C75.4626 9.96001 75.1426 9.91201 74.8333 9.91201C74.1613 9.91201 73.6066 10.0827 73.1693 10.424C72.7319 10.7653 72.4066 11.1973 72.1933 11.72C71.9799 12.2427 71.8733 12.776 71.8733 13.32C71.8733 13.9173 71.9959 14.4827 72.2413 15.016C72.4866 15.5387 72.8333 15.96 73.2813 16.28C73.7293 16.6 74.2573 16.76 74.8653 16.76C75.1853 16.76 75.5106 16.712 75.8413 16.616C76.1719 16.5093 76.4759 16.3387 76.7533 16.104C77.0413 15.8693 77.2599 15.5653 77.4093 15.192L79.5533 16.456C79.3293 17.0213 78.9613 17.5013 78.4493 17.896C77.9373 18.28 77.3559 18.5787 76.7053 18.792C76.0653 18.9947 75.4306 19.096 74.8013 19.096C73.9799 19.096 73.2279 18.9307 72.5453 18.6C71.8626 18.2587 71.2706 17.8107 70.7693 17.256C70.2679 16.6907 69.8786 16.0613 69.6013 15.368C69.3346 14.664 69.2013 13.9493 69.2013 13.224Z"
                fill="white" />
              <path
                d="M87.7689 10.968C87.7369 10.9253 87.6249 10.8453 87.4329 10.728C87.2409 10.6107 87.0009 10.488 86.7129 10.36C86.4249 10.2213 86.1102 10.1093 85.7689 10.024C85.4276 9.92801 85.0862 9.88001 84.7449 9.88001C83.8062 9.88001 83.3369 10.1947 83.3369 10.824C83.3369 11.208 83.5396 11.48 83.9449 11.64C84.3609 11.8 84.9529 11.992 85.7209 12.216C86.4462 12.4187 87.0702 12.6533 87.5929 12.92C88.1262 13.176 88.5369 13.5227 88.8249 13.96C89.1129 14.3867 89.2569 14.952 89.2569 15.656C89.2569 16.296 89.1396 16.84 88.9049 17.288C88.6702 17.7253 88.3502 18.0827 87.9449 18.36C87.5396 18.6267 87.0809 18.824 86.5689 18.952C86.0676 19.0693 85.5449 19.128 85.0009 19.128C84.1582 19.128 83.3049 19.0053 82.4409 18.76C81.5769 18.504 80.8142 18.1573 80.1529 17.72L81.3049 15.432C81.3476 15.4853 81.4862 15.5867 81.7209 15.736C81.9556 15.8747 82.2489 16.024 82.6009 16.184C82.9529 16.344 83.3369 16.4827 83.7529 16.6C84.1796 16.7067 84.6116 16.76 85.0489 16.76C85.9769 16.76 86.4409 16.4773 86.4409 15.912C86.4409 15.624 86.3182 15.4 86.0729 15.24C85.8382 15.0693 85.5129 14.9253 85.0969 14.808C84.6809 14.68 84.2116 14.536 83.6889 14.376C82.6436 14.056 81.8702 13.6667 81.3689 13.208C80.8782 12.7493 80.6329 12.0933 80.6329 11.24C80.6329 10.44 80.8196 9.76801 81.1929 9.22401C81.5769 8.66934 82.0889 8.25334 82.7289 7.97601C83.3689 7.68801 84.0676 7.54401 84.8249 7.54401C85.6249 7.54401 86.3822 7.68267 87.0969 7.96001C87.8116 8.22667 88.4196 8.50401 88.9209 8.79201L87.7689 10.968Z"
                fill="white" />
            </svg>

          </a>
        </div>

        <!-- <div class="fp-nav-action" @click="toggleFocus(!focusTree)">{{focusTree ? '全部目录':'聚焦文档'}}</div> -->

      </header>

      <div class="fp-doc-container" style="background-image: linear-gradient(#e5f6fe, #fff 20%);">

        <div :class="['fp-doc-tree',{'fp-hide-tree':hideTree},{'fp-open-tree':!hideTree},{'fp-focus-tree':focusTree}]">
          <div class="fp-tree-links">
            <div class="fp-tree-node-wrap">
              <!-- <div v-for="item in 1000">1</div> -->
              <tree-node v-if="fileTree.length > 0" :tree-data="fileTree" :active-file="currentFile"></tree-node>
            </div>
            <!-- <div class="fp-tree-footer">Files preview · <a target="_blank"
                href="https://gitee.com/Jioho/files-preview">Gitee 地址</a>
            </div> -->
          </div>
        </div>

        <div class="fp-doc-main">
          <div class="fp-doc-main-wrap">
            <div class="fp-doc-body">
              <div class="content">
                {{contentHTML}}
              </div>
              <div class="fp-tree-footer">Files preview · <a target="_blank"
                  href="https://gitee.com/Jioho/files-preview">Gitee 地址</a>
              </div>
            </div>

            <div class="fp-doc-anchor" v-if="anchor.length > 0">
              <ul class="sidebar-anchor-link" style="border-left: 1px solid #E2E8F0;">
                <li>
                  <tree-anchor-node :tree-data="anchor" :active-file="currentHash"></tree-anchor-node>
                </li>
              </ul>
            </div>
          </div>
        </div>

      </div>
    </div>
  </div>
</body>

<script>
  let fileTree = '{{fileTree}}';

  (function () {
    let docConfig = window.localStorage.getItem("FPDocConfig") || "{}";
    docConfig = JSON.parse(docConfig);

    function debounce(func, wait, immediate) {
      let timeout;
      return function () {
        let context = this;
        let args = arguments;
        if (timeout) clearTimeout(timeout);

        if (immediate) {
          var callNow = !timeout;
          timeout = setTimeout(() => {
            timeout = null;
          }, wait);
          if (callNow) func.apply(context, args);
        } else {
          timeout = setTimeout(function () {
            func.apply(context, args);
          }, wait);
        }
      };
    }

    Vue.component("tree-node", {
      template: `
      <ul class="sidebar-links">
        <li :class="['sidebar-group',...groupLinkStyle(item.relative)]" v-for="item in treeData">
          <p @click="toggleOpen(item.relative)" :class="['sidebar-heading',{close:!!closeKeys[item.relative]}]" v-if="item.name && item.name !== '/'"><a @click.stop :href="item.relative">{{item.name}}</a></p>
          <ul :class="['sidebar-group-items',{close:!!closeKeys[item.relative]}]" style="max-height:auto;" :ref="'groupItem_'+item.relative">
            <template v-if="item.files && item.files.length > 0">
              <li class="group-link-item" v-for="file in item.files">
                <a :href="file.relative" :class="['sidebar-link',{active:file.relative == activeFile}]">{{file.name}}</a>
              </li>
            </template>
            <li style="padding-left:0;" v-if="item.children && item.children.length > 0">
              <tree-node :treeData="item.children" :active-file="activeFile"></tree-node>
            </li>
          </ul>
        </li>
      </ul>
      `,
      props: {
        treeData: {
          type: Array,
          default: function () {
            return [];
          }
        },
        activeFile: {
          type: String,
          default: ""
        }
      },

      data() {
        return {
          closeKeys: {}
        };
      },

      methods: {
        toggleOpen(key) {
          if (key) {
            let isClose = !!this.closeKeys[key];
            let element = this.$refs["groupItem_" + key][0];

            if (!isClose) {
              element.style["max-height"] = element.clientHeight + "px";
            } else {
              // 时长0.2s
              setTimeout(() => {
                element.style["max-height"] = "none";
              }, 200);
            }

            setTimeout(() => {
              this.$set(this.closeKeys, key, !isClose);
            }, 1);
          }
        },

        groupLinkStyle(path) {
          let style = [];
          let urlArr = window.location.pathname.split("/"); // 移除最后一个文件名

          urlArr.pop();
          let url = urlArr.join("/") || "/";
          let pathUrl = encodeURI(path);

          if (url.indexOf(pathUrl) !== -1) {
            style.push("focus");
            style.push(url === pathUrl ? "focus-last" : "focus-broder");
          } else {
            style.push("default");
          }

          return style;
        }
      }
    });
    Vue.component("tree-anchor-node", {
      template: `
      <ul class="sidebar-anchor-link">
        <li class="sidebar-anchor-group" v-for="item in treeData">
          <p class="sidebar-anchor-heading" v-if="item.name && item.name !== '/'"><span>{{item.name}}</span></p>
          <ul class="sidebar-anchor-group-items" v-if="item.files && item.files.length > 0">
            <li v-for="file in item.files">
              <a :href="file.relative" :class="['sidebar-anchor-link','level_'+file.level,{active:file.relative == activeFile}]">{{file.name}}</a>
            </li>
            <li v-if="item.children && item.children.length > 0">
              <tree-anchor-node :treeData="item.children" :active-file="activeFile"></tree-anchor-node>
            </li>
          </ul>
        </li>
      </ul>
      `,
      props: {
        treeData: {
          type: Array,
          default: function () {
            return [];
          }
        },
        activeFile: {
          type: String,
          default: ""
        }
      }
    });
    var app = new Vue({
      el: "#app",

      data() {
        return {
          fileTree: [fileTree],
          currentFile: decodeURIComponent(window.location.pathname),
          currentHash: decodeURIComponent(window.location.hash),
          anchor: {},
          hideTree: window.innerWidth <= 700,
          prevWidth: window.innerWidth,
          focusTree: docConfig.focusTree || false
        };
      },

      mounted() {
        let _ts = this;

        this.createMenu();
        window.addEventListener("hashchange", this.changeHash, false);
        window.addEventListener("resize", this.changeWindowSize, false);
        this.toggleFocus(this.focusTree);
        this.highlightAll();
        this.initViewer();
      },

      beforeDestroy() {
        window.addEventListener("resize", this.changeWindowSize, false);
        window.removeEventListener("hashchange", this.changeHash, false);
      },

      methods: {
        highlightAll() {
          if (window.hljs && window.hljs.highlightAll) {
            window.hljs.highlightAll();
          } else {
            setTimeout(() => {
              this.highlightAll();
            }, 50);
          }
        },

        initViewer() {
          if (window.Viewer) {
            let viewer = new window.Viewer(
              document.querySelector(".fp-doc-body .content"),
              {
                inline: false,

                viewed() {
                  viewer.zoomTo(1);
                }
              }
            );
          } else {
            setTimeout(() => {
              this.initViewer();
            }, 50);
          }
        },

        setConfig(config = {}) {
          docConfig = Object.assign(docConfig, config);
          window.localStorage.setItem("FPDocConfig", JSON.stringify(docConfig));
        },

        toggleFocus(isFocus) {
          this.focusTree = isFocus;
          this.setConfig({
            focusTree: isFocus
          });
          this.$nextTick(() => {
            let activeElemt = document.querySelector(
              ".fp-doc-tree .sidebar-link.active"
            );
            let treeNodeElemt = document.querySelector(".fp-tree-node-wrap");

            if (!activeElemt || !treeNodeElemt) {
              return false;
            }

            let scrollTop =
              activeElemt.getBoundingClientRect().top - window.innerHeight / 2.5;
            treeNodeElemt.scrollTo({
              top: scrollTop,
              behavior: "smooth"
            });
          });
        },

        // 页面hash改变
        changeHash() {
          this.currentHash = decodeURIComponent(window.location.hash);
        },

        changeWindowSize: debounce(
          function () {
            this.hideTree = window.innerWidth <= 700;
          },
          10,
          false
        ),

        createMenu() {
          // 首先获取所有H标签，若页面中有h4，h5，h6则可以添加到参数中
          var headList = [...document.querySelectorAll("h1,h2,h3,h4,h5")]; // 将H标签构造成一棵树，就可以明确H标签之间的层级

          if (headList.length == 0) {
            return false;
          }

          var root = {
            children: []
          };
          var h = {
            node: headList[0],
            files: [
              {
                name: headList[0].innerText,
                relative: "#" + headList[0].id,
                level: headList[0].localName[1],
              }
            ],
            children: [],
            parent: root
          };

          if (!this.currentHash) {
            this.currentHash = "#" + headList[0].id || "";
          }

          root.children.push(h);
          headList.reduce(function (pre, cur) {
            var n = {
              node: cur,
              children: [],
              files: []
            };

            while (h.node.localName[1] - n.node.localName[1] >= 0) {
              h = h.parent;

              if (h === root) {
                break;
              }
            }

            n.parent = h;

            n.files.push({ ...n, name: cur.innerText, relative: "#" + cur.id, level: cur.localName[1] });
            h.children.push(n);
            h = n;
            return h;
          });
          console.log(root.children)
          this.anchor = root.children || [];
        }
      }
    });
  })();

</script>

<!-- 代码高亮的样式 -->
<script src="https://cdn.bootcdn.net/ajax/libs/highlight.js/11.0.1/highlight.min.js"></script>
<link href="https://cdn.bootcss.com/highlight.js/9.12.0/styles/atom-one-dark.min.css" rel="stylesheet" />

<!-- 图片预览服务 -->
<script src="https://cdn.bootcdn.net/ajax/libs/viewerjs/1.10.1/viewer.min.js"></script>
<link href="https://cdn.bootcdn.net/ajax/libs/viewerjs/1.10.1/viewer.min.css" rel="stylesheet">


</html>